openapi: 3.0.0

info:
  description: 'Levsha is open small work listing project'
  version: '1.0.0'
  title: 'Проект LEVSHA'
  contact:
    email: 'v.tyrin@icloud.com'
  license:
    name: 'MIT'
servers:
  - url: https://levsha-work.ru/levsha-api/
tags:
  - name: 'task'
    description: 'Access to task orders'
  - name: 'user'
    description: 'Operations about user'
  - name: 'location'
    description: 'Location-related options'
components:
  schemas:
    User:
      type: 'object'
      properties:
        uuid:
          type: 'string'
        firstname:
          type: 'string'
        secondname:
          type: 'string'
        lastname:
          type: 'string'
        date_created:
          type: 'string'
        last_change:
          type: 'string'
        date_deleted:
          type: 'string'
        is_deleted:
          type: 'boolean'
          default: false
        login:
          type: 'string'
        password:
          type: 'string'
        phone:
          type: 'string'
        email:
          type: 'string'
        vk_profile:
          type: 'string'
        ok_profile:
          type: 'string'
        fb_profile:
          type: 'string'
        ig_profile:
          type: 'string'
        tw_profile:
          type: 'string'
        yt_profile:
          type: 'string'
        be_profile:
          type: 'string'
        li_profile:
          type: 'string'
        hh_profile:
          type: 'string'
        phone_comfirmed:
          type: 'boolean'
          default: false
        email_confirmed:
          type: 'boolean'
          default: false
        photo_url:
          type: 'string'
        city:
          $ref: '#/components/schemas/City'
        starred_users:
          type: 'array'
          items:
            $ref: '#/components/schemas/User'
        hidden_users:
          type: 'array'
          items:
            $ref: '#/components/schemas/User'
      required:
        - uuid
        - firstname
        - lastname
        - password
        - phone

    TaskCategory:
      type: 'object'
      properties:
        id:
          type: 'number'
        name:
          type: 'string'
        sorting:
          type: 'number'
        is_deprecated:
          type: 'boolean'

    Task:
      type: 'object'
      properties:
        uuid:
          type: 'string'
        user:
          $ref: '#/components/schemas/User'
        date_created:
          type: 'string'
        is_deleted:
          type: 'boolean'
        is_favorite:
          type: 'boolean'
        title:
          type: 'string'
        description:
          type: 'string'
        price:
          type: 'integer'
        unit:
          type: 'string'
        have_constant_price:
          type: 'boolean'
        date_start:
          type: 'string'
        date_finish:
          type: 'string'
        district:
          $ref: '#/components/schemas/District'
        category:
          $ref: '#/components/schemas/TaskCategory'
        images:
          type: 'array'
          items:
            $ref: '#/components/schemas/TaskImage'

    TaskImage:
      type: 'object'
      properties:
        uuid:
          type: 'string'
        date_created:
          type: 'string'
        date_deleted:
          type: 'string'
        is_deleted:
          type: 'boolean'
        url:
          type: 'string'
        task_id:
          type: 'string'
        user_id:
          type: 'string'

    Message:
      type: 'object'
      properties:
        id:
          type: 'integer'
          required: ['true']
        user_from:
          type: 'integer'
          required: ['true']
        user_to:
          type: 'integer'
          required: ['true']
        task_id:
          type: 'integer'
        message:
          type: 'string'
        date_created:
          type: 'string'
        date_read:
          type: 'string'
        is_deleted:
          type: 'boolean'

    Notification:
      type: 'object'
      properties:
        id:
          type: 'number'
        user_id:
          type: 'number'
        title:
          type: 'string'
        message:
          type: 'string'
        date_created:
          type: 'string'
        date_read:
          type: 'string'
        payload:
          type: 'string'
        notification_type_id:
          type: 'number'

    NotificationType:
      type: object
      properties:
        id:
          type: 'number'
        name:
          type: 'string'

    City:
      type: 'object'
      properties:
        id:
          type: 'integer'
          format: 'int32'
        name:
          type: 'string'
        is_deleted:
          type: 'boolean'
          default: false
      required:
        - id
        - name
        - is_deleted

    District:
      type: 'object'
      properties:
        id:
          type: 'integer'
        name:
          type: 'string'
        city_id:
          type: 'integer'
        is_deleted:
          type: 'boolean'
          default: false
      required:
        - id
        - name
        - city_id
        - is_deleted

    SignInParameters:
      type: object
      properties:
        phone:
          type: string
        password:
          type: string
      required:
        - phone
        - password

    ApiResponse:
      type: 'object'
      properties:
        code:
          type: 'integer'
          format: 'int32'
        type:
          type: 'string'
        message:
          type: 'string'
  securitySchemes:
    cookieAuth: # arbitrary name for the security scheme; will be used in the "security" key later
      type: apiKey
      in: cookie
      name: JSESSIONID # cookie name
security:
  - cookieAuth: []
paths:
  /city:
    get:
      tags:
        - 'location'
      summary: 'Get list of current cities'
      operationId: 'getCity'
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: 'array'
                items:
                  $ref: '#/components/schemas/City'
        400:
          description: 'Server error'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'

  /city/{city_id}/district:
    get:
      tags:
        - 'location'
      summary: 'Get list of current cities'
      operationId: 'getDistrictsByCityId'
      parameters:
        - name: city_id
          in: 'path'
          required: true
          description: 'Id of queried city'
          schema:
            type: 'integer'
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: 'array'
                items:
                  $ref: '#/components/schemas/District'
        400:
          description: 'Server error'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'

  /task:
    get:
      tags:
        - 'task'
      summary: 'Get list of tasks'
      operationId: 'getTasks'
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Task'
        400:
          description: 'Server error'
    put:
      tags:
        - 'task'
      summary: 'Add a new task on board'
      description: ''
      operationId: 'addTask'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Task'
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'

        405:
          description: 'Invalid input'
  /user/task:
    get:
      tags:
        - 'task'
      summary: 'Get list of tasks'
      operationId: 'getUserTasks'
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Task'
        400:
          description: 'Server error'

  /task/item/{task_id}:
    get:
      tags:
        - task
      summary: Get an existing task detailed
      description: ''
      operationId: getTask
      parameters:
        - name: task_id
          in: path
          required: true
          schema:
            type: string

      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
        400:
          description: 'Server error'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
        404:
          description: Task not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
    post:
      tags:
        - task
      summary: Update an existing task
      description: ''
      operationId: updateTask
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Task'
      parameters:
        - name: task_id
          in: path
          required: true
          schema:
            type: string

      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'

        400:
          description: Invalid data supplied
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
        404:
          description: Task not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
        405:
          description: Validation exception
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
    delete:
      tags:
        - task
      summary: Hide an existing task
      description: ''
      operationId: deleteTask
      parameters:
        - name: task_id
          in: path
          required: true
          schema:
            type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'

        400:
          description: Invalid data supplied
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'

  /task/item/{task_id}/fav:
    get:
      tags:
        - 'task'
      summary: 'Adds or removes task item to favorites'
      description: 'Set fav flag'
      operationId: 'setFavoritesFlag'
      parameters:
        - name: 'task_id'
          in: 'path'
          description: ID of task
          required: true
          schema:
            type: string
        - name: 'value'
          in: 'query'
          description: To fav or not by boolean
          required: true
          schema: 
            type: boolean
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
        400:
          description: Invalid data supplied
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'

  /task/by_location/{location_id}:
    get:
      tags:
        - 'task'
      summary: 'Finds tasks by location'
      description: 'Get list of first tasks by location id'
      operationId: 'findTasksByLocation'
      parameters:
        - name: 'location_id'
          in: 'path'
          description: 'Id of queried location'
          required: true
          schema:
            type: 'integer'
        - name: 'page'
          in: 'query'
          description: 'Status values that need to be considered for filter'
          required: false
          schema:
            type: integer
      responses:
        200:
          description: 'successful operation'
          content:
            application/json:
              schema:
                type: 'array'
                items:
                  $ref: '#/components/schemas/Task'
        400:
          description: 'Server error'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
  /task/category:
    get:
      tags:
        - 'task'
      summary: 'Get list of task categories'
      operationId: 'getTaskCategories'
      responses:
        200:
          description: 'Get list of existing task categories'
          content:
            application/json:
              schema:
                type: 'array'
                items:
                  $ref: '#/components/schemas/TaskCategory'
        400:
          description: 'Server error'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
    put:
      tags:
        - 'task'
      summary: 'Create new task category'
      operationId: 'createTaskCategory'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskCategory'
      responses:
        default:
          description: 'successful operation'
        400:
          description: 'Server error'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'

  /task/category/{task_category_id}:
    post:
      tags:
        - 'task'
      summary: 'Update given task category'
      operationId: 'updateTaskCategory'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskCategory'
      parameters:
        - name: 'task_category_id'
          in: 'path'
          description: 'Id of queried location'
          required: true
          schema:
            type: 'integer'
      responses:
        default:
          description: 'successful operation'
        404:
          description: 'Not found'
    delete:
      tags:
        - 'task'
      summary: 'Removes given task category'
      operationId: 'removeTaskCategory'
      parameters:
        - name: 'task_category_id'
          in: 'path'
          description: 'Id of queried location'
          required: true
          schema:
            type: 'integer'
      responses:
        200:
          description: OK
        400:
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'

  /task/by_favorites:
    get:
      tags:
        - 'task'
      summary: 'List of task favorites of current user'
      operationId: 'getMyFavoriteTasks'
      responses:
        200:
          description: 'successful operation'
          content:
            application/json:
              schema:
                type: 'array'
                items:
                  $ref: '#/components/schemas/Task'
        400:
          description: 'Server error'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'

  /task/image:
    post:
      tags:
        - 'task'
      summary: 'Upload new image to server before corresponding task is created'
      operationId: uploadTaskImage"
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                taskImage:
                  type: string
                  format: binary
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskImage'
        500:
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
        405:
          description: Invalid input
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'

  /user:
    get:
      tags:
        - 'user'
      summary: 'Get current user from session, eg after reload of app'
      description: ''
      operationId: 'getCurrentUser'
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        400:
          description: 'Server error'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
        404:
          description: 'Session not found / invalid / expired'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
    put:
      tags:
        - 'user'
      summary: 'Create user'
      description: 'Registration of new user'
      operationId: 'createUser'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        400:
          description: 'Form invalid'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'

  /user/login:
    post:
      tags:
        - 'user'
      summary: 'Logs user into the system'
      description: ''
      operationId: 'loginUser'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignInParameters'
      responses:
        200:
          description: 'successful operation'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        401:
          description: 'Invalid username/password supplied'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
  /user/logout:
    get:
      tags:
        - 'user'
      summary: 'Logs out current logged in user session'
      description: ''
      operationId: 'logoutUser'
      parameters: []
      responses:
        default:
          description: 'successful operation'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
        400:
          description: 'server error'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
  /user/{username}:
    get:
      tags:
        - 'user'
      summary: 'Get user by user name'
      description: ''
      operationId: 'getUserByName'
      parameters:
        - name: 'username'
          in: 'path'
          description: 'The name that needs to be fetched. Use user1 for testing. '
          required: true
          schema:
            type: 'string'
      responses:
        200:
          description: 'successful operation'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        400:
          description: 'Invalid username supplied'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
        404:
          description: 'User not found'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
    post:
      tags:
        - 'user'
      summary: 'Updated user'
      description: 'This can only be done by the logged in user.'
      operationId: 'updateUser'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
      parameters:
        - name: 'username'
          in: 'path'
          description: 'name that need to be updated'
          required: true
          schema:
            type: 'string'
      responses:
        400:
          description: 'Invalid user supplied'
        404:
          description: 'User not found'
    delete:
      tags:
        - 'user'
      summary: 'Delete user'
      description: 'This can only be done by the logged in user with privilegy.'
      operationId: 'deleteUser'
      parameters:
        - name: 'username'
          in: 'path'
          description: 'The name that needs to be deleted'
          required: true
          schema:
            type: 'string'
      responses:
        400:
          description: 'Invalid username supplied'
        404:
          description: 'User not found'

externalDocs:
  description: 'Find out more about Swagger'
  url: 'http://swagger.io'
